package com.example.shiwu.util;

import android.app.Activity;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

public abstract class BaseView<T> extends RecyclerView.ViewHolder {
    private static final String TAG = "BaseView";

    /**点击事件
     */
    public interface OnViewClickListener {
        /**
         * @param bv
         * @param v
         */
        void onViewClick(@NonNull BaseView bv, @NonNull View v); //BaseView<T>泛型太麻烦，不利于多层View传递
    }

    /**数据改变回调接口
     * (Object) getData() - 改变的数据
     */
    public interface OnDataChangedListener {
        void onDataChanged();
    }

    /**
     * 需要在BaseView子类手动回调 onViewClickListener.onViewClick(...)
     */
    public OnViewClickListener onViewClickListener;//数据改变回调监听回调的实例
    public BaseView<T> setOnViewClickListener(OnViewClickListener onViewClickListener) {
        this.onViewClickListener = onViewClickListener;
        return this;
    }

    /**
     * 需要在BaseView子类手动回调 onViewClickListener.onDataChanged()
     */
    public OnDataChangedListener onDataChangedListener;//数据改变回调监听回调的实例
    /**设置数据改变事件监听回调
     * @param listener
     */
    public BaseView<T> setOnDataChangedListener(OnDataChangedListener listener) {
        onDataChangedListener = listener;
        return this;
    }


    /**
     * @param context
     * @param layoutResId
     * @see #BaseView(Activity, int, ViewGroup)
     */
    public BaseView(Activity context, @LayoutRes int layoutResId) {
        this(context, layoutResId, null);
    }

    /**
     * @param context
     * @param layoutResId
     * @param parent TODO 如果itemView不能占满宽度 或 高度不对，一般是RecyclerView的问题，可通过传parent解决
     */
    public BaseView(Activity context, @LayoutRes int layoutResId, ViewGroup parent) {
        this(context, context.getLayoutInflater().inflate(layoutResId, parent, false));
    }
    /**
     * 传入的Activity,可在子类直接使用
     */
    public final Activity context;
    /**
     * @param context
     * @param itemView
     */
    public BaseView(Activity context, View itemView) {
        super(itemView);
        this.context = context;
    }





    /**通过id查找并获取控件，使用时不需要强转
     * @param id
     * @return
     */
    @SuppressWarnings("unchecked")
    public <V extends View> V findView(int id) {
        return (V) itemView.findViewById(id);
    }
    /**通过id查找并获取控件，使用时不需要强转
     * @param id
     * @return
     */
    public <V extends View> V findViewById(int id) {
        return findView(id);
    }
    /**通过id查找并获取控件，并setOnClickListener
     * @param id
     * @param listener
     * @return
     */
    public <V extends View> V findView(int id, View.OnClickListener listener) {
        V v = findView(id);
        v.setOnClickListener(listener);
        return v;
    }
    /**通过id查找并获取控件，并setOnClickListener
     * @param id
     * @param listener
     * @return
     */
    public <V extends View> V findViewById(int id, View.OnClickListener listener) {
        return findView(id, listener);
    }

    public T data = null;
    /**
     * data在列表中的位置
     * @must 只使用bindView(int position, T data)方法来设置position，保证position与data对应正确
     */
    public int position = 0;
    /**
     * 视图类型，部分情况下需要根据viewType使用不同layout，对应Adapter的itemViewType
     */
    public int viewType = 0;
    /**
     * 是否已被选中
     */
    public boolean selected = false;

    /**创建一个新的View
     * @return
     */
    public View createView() {
        return itemView;
    }

    /**获取itemView的宽度
     * @warn 只能在createView后使用
     * @return
     */
    public int getWidth() {
        return itemView.getWidth();
    }
    /**获取itemView的高度
     * @warn 只能在createView后使用
     * @return
     */
    public int getHeight() {
        return itemView.getHeight();
    }





    /**设置并显示内容，建议在子类bindView内this.data = data;
     * @warn 只能在createView后使用
     * @param data - 传入的数据
     * @param position - data在列表中的位置
     * @param viewType - 视图类型，部分情况下需要根据viewType使用不同layout
     */
    public void bindView(T data, int position, int viewType) {
        this.position = position;
        this.viewType = viewType;
        bindView(data);
    }
    /**设置并显示内容，建议在子类bindView内this.data = data;
     * @warn 只能在createView后使用
     * @param data_ - 传入的数据
     */
    public void bindView(T data_) {
        if (data_ == null) {
            Log.w(TAG, "bindView data_ == null");
        }
        this.data = data_;

        //不一定要用单选功能，实现也不一定要用这种方式，这里写会影响所有BaseView子类的性能，子类写更好 itemView.setSelected(selected);
    }

    /**获取可见性
     * @warn 只能在createView后使用
     * @return 可见性 (View.VISIBLE, View.GONE, View.INVISIBLE);
     */
    public int getVisibility() {
        return itemView.getVisibility();
    }
    /**设置可见性
     * @warn 只能在createView后使用
     * @param visibility - 可见性 (View.VISIBLE, View.GONE, View.INVISIBLE);
     */
    public void setVisibility(int visibility) {
        itemView.setVisibility(visibility);
    }


    /**设置背景
     * @warn 只能在createView后使用
     * @param resId
     */
    public void setBackground(int resId) {
        itemView.setBackgroundResource(resId);
    }


    //	/**性能不好
    //	 * @param id
    //	 * @param s
    //	 */
    //	public void setText(int id, String s) {
    //		TextView tv = (TextView) findViewById(id);
    //		tv.setText(s);
    //	}



    //resources方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

    public Resources resources;
    public final Resources getResources() {
        if(resources == null) {
            resources = context.getResources();
        }
        return resources;
    }

    public String getString(int id) {
        return getResources().getString(id);
    }
    public int getColor(int id) {
        return getResources().getColor(id);
    }
    public Drawable getDrawable(int id) {
        return getResources().getDrawable(id);
    }
    public float getDimension(int id) {
        return getResources().getDimension(id);
    }
    //resources方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    
    //启动新Activity方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    /**销毁并回收内存，建议在对应的View占用大量内存时使用
     * @warn 只能在UI线程中调用
     */
    public void onDestroy() {
        if (itemView != null) {
            try {
                itemView.destroyDrawingCache();
            } catch (Exception e) {
                Log.w(TAG, "onDestroy  try { itemView.destroyDrawingCache();" +
                        " >> } catch (Exception e) {\n" + e.getMessage());
            }
        }

        onDataChangedListener = null;

        data = null;
        position = 0;

    }

}

